/*
 * Created: 2022-02-18 10:01:00
 * Author : 涛涛涛
 */

/** 类型转换静态类 */
class SwitchType {
    public static string(data: number) {
        if (data === null || data === undefined || data === 0) return '';
        if (typeof data !== 'number') return data;
        return String(data);
    }
    public static boolean(data: 1 | 0) {
        if (data === null || data === undefined) return false;
        if (data !== 0 && data !== 1) return data;
        return Boolean(data);
    }
    public static number(data: string): number;
    public static number(data: boolean): 0 | 1;
    public static number(data: string | boolean): number {
        if (data === null || data === undefined) return 0;
        if (typeof data !== 'string' && typeof data !== 'boolean') return data;
        return Number(data);
    }
}

/** 注入值,将新对象中有的所有值,全部拷贝到旧对象中 */
export class Immit {
    //TODO:增加一个排除项,  直接在response的拦截器中,进行数据格式的转换
    immit?<T extends { [key in any]: any } = any>(data: Partial<T>, exclude?: (keyof this)[]) {
        /** 类型完全相同的情况处理
         * 类型完全相同的情况,已经是经过我处理一次的数据了,不再会有null什么乱七八遭的东西了.
         */
        const classIdenticalHandle = () => {
            if (data) {
                for (const key in this) {
                    /** 如果是需要被排除的内容,直接跳过本次循环 */
                    if (exclude?.includes(key)) continue;
                    this[key] = data[key];
                }
            }
        };
        /** 类型不相同的情况处理 */
        const classDifference = () => {
            if (data) {
                for (const key in this) {
                    /** 如果是需要被排除的内容,直接跳过本次循环 */
                    if (exclude?.includes(key)) continue;
                    /** 判断自身属性,是否可直接转换 */
                    if (SwitchType[typeof this[key]]) {
                        /** 可以直接转换则进行转换 */
                        this[key] = SwitchType[typeof this[key]](data[key]);
                    } else {
                        this[key] = data[key];
                    }
                }
            }
        };
        /** 不同情况,不同的处理方式. */
        if (data?.__proto__?.constructor === (this as any)?.__proto__?.constructor) {
            classIdenticalHandle();
        } else {
            classDifference();
        }
        return this;
    }
}
